import { nanoid } from 'nanoid'
import ConstantUtil from '@/utils/graph-utils/constantUtil.js'

export default {
  // 获取框架提供的节点类型
  getX6Shapes() {
    return ['rect', 'circle', 'ellipse', 'path', 'polygon', 'polyline', 'cylinder', 'image', 'text', 'text-block']
  },

  // 判断节点是否可改变大小
  isResizedNodeShape(node) {
    return !this.isCustomizeNode(node.shape) || this.isBusNode(node) ||
     this.isLineNode(node) || this.isTextNode(node)
  },

  // 是否为自定义节点类型
  isCustomizeNode(nodeShape) {
    const x6Shapes = this.getX6Shapes()
    return x6Shapes.indexOf(nodeShape) === -1
  },

  // 是否为母线节点
  isBusNode(metaType) {
    return metaType && ConstantUtil.isBusType(metaType)
  },

  // 是否为线路节点
  isLineNode(metaType) {
    return metaType && ConstantUtil.isLineType(metaType)
  },

  // 是否为文本节点
  isMeasureNode(metaType) {
    return metaType && ConstantUtil.isMeasureType(metaType)
  },

  // 是否为故障节点
  isFaultNode(metaType) {
    return metaType && ConstantUtil.isFaultType(metaType)
  },

  BackgroundColor: '#333b50',

  // 获取graph默认配置
  getDefaultGraphConfig() {
    return {
      grid: {
        size: 5,
        visible: true,
        args: {
          color: '#a0a0a0',
          thickness: 1
        }
      },
      // autoResize: true,
      background: {
        color: this.BackgroundColor
      },
      clipboard: {
        enabled: true
        // useLocalStorage: true
      },
      connecting: {
        snap: true,
        allowBlank: true,
        allowLoop: false,
        allowNode: true, // 使用判断函数时，链接桩不能够正常使用了，问题原因未知
        allowEdge: false,
        highlight: true,
        anchor: 'orth',
        router: 'manhattan',
        connectionPoint: 'anchor'
      },
      history: true,
      keyboard: {
        enabled: true
      },
      minimap: {
        enabled: true,
        // container: miniMapContainer,
        width: 140,
        height: 140,
        graphOptions: {
          background: {
            color: '#333b50'
          }
        }
      },
      mousewheel: {
        enabled: true,
        modifiers: ['ctrl', 'meta']
      },
      resizing: {
        enabled: (node) => {
          return !this.isCustomizeNode(node.shape) || node.data.enableResize
        },
        minWidth: (node) => {
          return node.data.minWidth
        },
        maxWidth: (node) => {
          return node.data.maxWidth
        },
        minHeight: (node) => {
          return node.data.minHeight
        },
        maxHeight: (node) => {
          return node.data.maxHeight
        }
      },
      selecting: {
        enabled: true,
        rubberband: true,
        movable: true,
        showNodeSelectionBox: true,
        showEdgeSelectionBox: true
      },
      snapline: {
        enabled: true,
        sharp: true
      },
      scroller: {
        enabled: true,
        pageVisible: true,
        pageBreak: false,
        pannable: true,
        modifiers: ['ctrl', 'meta'],
        autoResize: false,
        autoResizeOptions: {
          minWidth: 800,
          minHeight: 800
        }
      },
      translating: {
        restrict: true
      },
      scaling: {
        min: 0.5,
        max: 5
      }
    }
  },

  // 获取拖拽面板默认配置
  getDefaultStencilConfig() {
    return {
      title: '模板',
      // target: this.$store.state.graphModule.graph,
      search: (cell, keyword, groupName, stencil) => {
        if (keyword) {
          return cell.attr('text/text').includes(keyword)
        }
        return true
      },
      collapsable: true,
      stencilGraphWidth: 180,
      stencilGraphHeight: 400,
      stencilGraphOptions: {
        scroller: true,
        grid: 10
      },
      groups: this.getStencilGroups(),
      layoutOptions: {
        columns: 3,
        rowHeight: 120
      },
      getDragNode: (sourceNode, options) => {
        const targetNode = sourceNode.clone()
        if (targetNode.hasTools()) {
          targetNode.removeTools()
        }
        return targetNode
      },
      getDropNode: (draggingNode, options) => {
        const dropNode = draggingNode.clone()
        if (!dropNode.data) {
          dropNode.data = {}
        }
        dropNode.data.flagId = nanoid(10)
        dropNode.data.id = nanoid(10)
        return dropNode
      }
    }
  },

  // 拖拽面板Group配置
  getStencilGroups() {
    return [{
      name: 'basicGroup',
      title: '基本图元'
    },
    {
      name: 'elecGroup',
      title: '设备图元'
    },
    {
      name: 'measureGroup',
      title: '量测图元'
    },
    {
      name: 'otherGroup',
      title: '其他图元'
    }]
  },

  getStencilGroupInfo(name) {
    const groups = this.getStencilGroups()
    for (const group of groups) {
      if (group.name === name) {
        return group
      }
    }
  },

  // 自定义节点的类型信息
  getMetaTypes() {
    return [{
      value: 'Breaker',
      label: '开关'
    },
    {
      value: 'Bus',
      label: '母线'
    },
    {
      value: 'Line',
      label: '线路'
    },
    {
      value: 'Transformer',
      label: '变压器'
    },
    {
      value: 'Substation',
      label: '厂站'
    },
    {
      value: '测点',
      label: '测点'
    },
    {
      value: 'Channel',
      label: '通道'
    },
    {
      value: 'Working conditions',
      label: '工况'
    },
    {
      value: 'FaultOther',
      label: 'Fault'
    },
    {
      value: 'other',
      label: '其他'
    }]
  },

  // 获取节点类型名称
  getMetaTypeName(type) {
    const metaTypes = this.getMetaTypes()
    const resultType = metaTypes.find(metaType => {
      return metaType.value === type
    })
    return resultType ? resultType.label : type
  },

  // 获取图形文件类型
  getGraphFileTypes() {
    return [{
      type: '1',
      title: '接线图'
    }, {
      type: '2',
      title: '工况图'
    }]
  },

  // 获取创建节点时可以使用的节点类型
  getNodeTagConfig() {
    return [{
      label: '矩形',
      value: 'rect'
    }, {
      label: '圆形',
      value: 'circle'
    }, {
      label: '椭圆',
      value: 'ellipse'
    }, {
      label: '文本',
      value: 'text'
    }, {
      label: '路径',
      value: 'path'
    }, {
      label: '线段',
      value: 'line'
    }, {
      label: '多边线',
      value: 'polyline'
    }, {
      label: '多边形',
      value: 'polygon'
    }]
  },

  // 获取节点属性配置
  getNodeAttrConfig() {
    return [{
      label: 'ref',
      value: 'ref'
    }, {
      label: 'refX(元素左上角 x 坐标)',
      value: 'refX'
    }, {
      label: 'refX2(元素左上角 y 坐标,同时指定相对偏移量和绝对偏移量时使用)',
      value: 'refX2'
    }, {
      label: 'refY(元素左上角 y 坐标)',
      value: 'refY'
    }, {
      label: 'refY2(元素左上角 x 坐标,同时指定相对偏移量和绝对偏移量时使用)',
      value: 'refY2'
    }, {
      label: 'refDx(元素右下角 x 坐标)',
      value: 'refDx'
    }, {
      label: 'refDy(元素右下角 y 坐标)',
      value: 'refDy'
    }, {
      label: 'refWidth(元素宽度)',
      value: 'refWidth'
    }, {
      label: 'refWidth2(元素宽度,同时指定绝对宽度和相对宽度时使用)',
      value: 'refWidth2'
    }, {
      label: 'refHeight(元素高度)',
      value: 'refHeight'
    }, {
      label: 'refHeight2(元素高度,同时指定绝对高度和相对高度时使用)',
      value: 'refHeight2'
    }, {
      label: 'refR(元素半径)',
      value: 'refR'
    }, {
      label: 'refCx(元素中心 x 坐标)',
      value: 'refCx'
    }, {
      label: 'refCy(元素中心 y 坐标)',
      value: 'refCy'
    }, {
      label: 'refRx(元素的 rx 属性)',
      value: 'refRx'
    }, {
      label: 'refRy(元素的 ry 属性)',
      value: 'refRy'
    }, {
      label: 'fill(填充颜色)',
      value: 'fill'
    }, {
      label: 'stroke(线路颜色)',
      value: 'stroke'
    }, {
      label: 'strokeWidth(线宽)',
      value: 'strokeWidth'
    }, {
      label: 'text(文本内容)',
      value: 'text'
    }, {
      label: 'fontFamily(字体名称)',
      value: 'fontFamily'
    }, {
      label: 'fontSize(字体大小)',
      value: 'fontSize'
    }, {
      label: 'fontWeight(字体粗细bold/normal)',
      value: 'fontWeight'
    }, {
      label: 'fontStyle(字体倾斜italic/normal)',
      value: 'fontStyle'
    }, {
      label: 'refPointsKeepOffset',
      value: 'refPointsKeepOffset'
    }, {
      label: 'points(点值)',
      value: 'refPoints'
    }, {
      label: 'x1',
      value: 'x1'
    }, {
      label: 'y1',
      value: 'y1'
    }, {
      label: 'x2',
      value: 'x2'
    }, {
      label: 'y2',
      value: 'y2'
    }]
  },

  createSelectOption(label, value) {
    return {
      label: label,
      value: value
    }
  },

  getSvgAttrs(tagName) {
    const configs = []
    switch (tagName) {
      case 'line':
        configs.push(this.createSelectOption('x1', 'x1'))
        configs.push(this.createSelectOption('y1', 'y1'))
        configs.push(this.createSelectOption('x2', 'x2'))
        configs.push(this.createSelectOption('y2', 'y2'))
        break
      case 'rect':
        configs.push(this.createSelectOption('refX', 'refX'))
        configs.push(this.createSelectOption('refY', 'refY'))
        configs.push(this.createSelectOption('refWidth', 'refWidth'))
        configs.push(this.createSelectOption('refHeight', 'refHeight'))
        configs.push(this.createSelectOption('refRx', 'refRx'))
        configs.push(this.createSelectOption('refRy', 'refRy'))
        configs.push(this.createSelectOption('magnet', 'magnet'))
        break
      case 'circle':
        configs.push(this.createSelectOption('refCx', 'refCx'))
        configs.push(this.createSelectOption('refCy', 'refCy'))
        configs.push(this.createSelectOption('refR', 'refR'))
        break
      case 'ellipse':
        configs.push(this.createSelectOption('refCx', 'refCx'))
        configs.push(this.createSelectOption('refCy', 'refCy'))
        configs.push(this.createSelectOption('refRx', 'refRx'))
        configs.push(this.createSelectOption('refRy', 'refRy'))
        break
      case 'polygon':
        configs.push(this.createSelectOption('refPointsKeepOffset', 'refPointsKeepOffset'))
        configs.push(this.createSelectOption('refPointsResetOffset(refPoints)', 'refPoints'))
        break
      case 'polyline':
        configs.push(this.createSelectOption('refPointsKeepOffset', 'refPointsKeepOffset'))
        configs.push(this.createSelectOption('refPointsResetOffset(refPoints)', 'refPoints'))
        break
      case 'text':
        configs.push(this.createSelectOption('refX', 'refX'))
        configs.push(this.createSelectOption('refY', 'refY'))
        configs.push(this.createSelectOption('text', 'text'))
        break
      case 'path':
        configs.push(this.createSelectOption('d', 'd'))
        break
    }
    return configs
  },

  getStyleAttrs(tagName) {
    const configs = []
    if (tagName === 'text') {
      configs.push(this.createSelectOption('stroke', 'stroke'))
      configs.push(this.createSelectOption('font-family', 'font-family'))
      configs.push(this.createSelectOption('font-size', 'font-size'))
      configs.push(this.createSelectOption('font-weight', 'font-weight'))
      configs.push(this.createSelectOption('font-style', 'font-style'))
      configs.push(this.createSelectOption('text-decoration', 'text-decoration'))
      configs.push(this.createSelectOption('word-spacing', 'word-spacing'))
      configs.push(this.createSelectOption('letter-spacing', 'letter-spacing'))
      configs.push(this.createSelectOption('text-anchor', 'text-anchor'))
    } else if (tagName === 'polyline') {
      configs.push(this.createSelectOption('stroke', 'stroke'))
      configs.push(this.createSelectOption('stroke-width', 'stroke-width'))
      configs.push(this.createSelectOption('stroke-opacity(线的不透明度)', 'stroke-opacity'))
      configs.push(this.createSelectOption('stroke-dasharray(点线或虚线)', 'strokeD-dasharray'))
      configs.push(this.createSelectOption('stroke-linecap(线的头尾形状)', 'stroke-linecap'))
      configs.push(this.createSelectOption('stroke-linejoin(线段交叉效果)', 'stroke-linejoin'))
    } else {
      configs.push(this.createSelectOption('fill', 'fill'))
      configs.push(this.createSelectOption('stroke', 'stroke'))
      configs.push(this.createSelectOption('stroke-width', 'stroke-width'))
    }
    return configs
  },

  // 获取样式名称
  getAttrName(attr) {
    switch (attr) {
      case 'fill':
        return '填充色'
      case 'stroke':
        return '线路颜色'
      case 'stroke-width':
        return '线路宽度'
      case 'text':
        return '文本'
      case 'font-family':
        return '字体'
      case 'font-size':
        return '字体大小'
      default:
        return attr
    }
  },

  isNumberAttrType(type) {
    const numberTypes = ['refX', 'refY', 'refRx', 'refRy', 'refCx', 'refCy',
      'refWidth', 'refHeight', 'x1', 'y1', 'x2', 'y2',
      'stroke-width', 'stroke-opacity', 'font-size']
    return numberTypes.indexOf(type) !== -1
  },

  isColorAttrType(type) {
    const colorTypes = ['fill', 'stroke']
    return colorTypes.indexOf(type) !== -1
  },

  isSelectAttrType(type) {
    const selectTypes = ['stroke-linecap', 'stroke-linecap',
      'font-family', 'font-weight',
      'font-style', 'text-decoration']
    return selectTypes.indexOf(type) !== -1
  },

  // 是否为样式属性
  isStyleAttr(attr) {
    const types = ['fill', 'stroke', 'font']
    for (const type of types) {
      if (attr.indexOf(type) !== -1) {
        return true
      }
    }
    return false
  },

  getSelectOptions(type) {
    const options = []
    switch (type) {
      case 'stroke-linecap':
        options.push(this.createSelectOption('butt', 'butt'))
        options.push(this.createSelectOption('round', 'round'))
        options.push(this.createSelectOption('square', 'square'))
        break
      case 'stroke-linejoin':
        options.push(this.createSelectOption('miter(尖的)', 'miter'))
        options.push(this.createSelectOption('round(圆的)', 'round'))
        options.push(this.createSelectOption('bevel(平的)', 'bevel'))
        break
      case 'font-family':
        options.push(this.createSelectOption('serif', 'serif'))
        options.push(this.createSelectOption('sans-serif', 'sans-serif'))
        options.push(this.createSelectOption('monospace', 'monospace'))
        options.push(this.createSelectOption('fantasy', 'fantasy'))
        options.push(this.createSelectOption('cursive', 'cursive'))
        options.push(this.createSelectOption('Helvetica Neue', 'Helvetica Neue'))
        options.push(this.createSelectOption('Helvetica', 'Helvetica'))
        options.push(this.createSelectOption('PingFang SC', 'PingFang SC'))
        options.push(this.createSelectOption('Hiragino Sans GB', 'Hiragino Sans GB'))
        options.push(this.createSelectOption('Microsoft YaHei', 'Microsoft YaHei'))
        options.push(this.createSelectOption('Arial', 'Arial'))
        break
      case 'font-weight':
        options.push(this.createSelectOption('bold', 'bold'))
        options.push(this.createSelectOption('normal', 'normal'))
        break
      case 'font-style':
        options.push(this.createSelectOption('italic', 'italic'))
        options.push(this.createSelectOption('normal', 'normal'))
        break
      case 'text-decoration':
        options.push(this.createSelectOption('none', 'none'))
        options.push(this.createSelectOption('underline', 'underline'))
        options.push(this.createSelectOption('overline', 'overline'))
        options.push(this.createSelectOption('line-through', 'line-through'))
        break
    }
    return options
  },

  // 获取属性配置说明
  getAttrConfigDesc() {
    const configDescs = []
    configDescs.push({
      name: 'ref',
      desc: '指向一个元素的 CSS 选择器，指代的元素是那些以 ref 开头的属性的参照元素。'
    })
    configDescs.push({
      name: 'refX',
      desc: '设置元素 x 坐标，目标 x 坐标相对于 ref 指代的参照元素的左上角 x 坐标（参照 x 坐标）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 50%）时，表示目标 x 坐标是参照 x 坐标相对于参照元素宽度百分比的相对偏移量。例如 refX: 0.5 表示，目标 x 坐标在参照 x 坐标基础上，向右偏移参照宽度的 50%。',
        '当其值 <0 或 >1 时，表示目标 x 坐标是参照 x 坐标的绝对偏移量。例如 refX: 20 表示，目标 x 坐标在参照 x 坐标基础上，向右偏移 20px。'
      ]
    })
    configDescs.push({
      name: 'refX2',
      desc: '与 refX 一样，当需要同时指定相对偏移量和绝对偏移量时使用。'
    })
    configDescs.push({
      name: 'refY',
      desc: '设置元素 y 坐标，目标 y 坐标相对于 ref 指代的参照元素的左上角 y 坐标（参照 y 坐标）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 50%）时，表示目标 y 坐标是参照 y 坐标相对于参照元素高度百分比的相对偏移量。例如 refY: 0.5 表示，目标 y 坐标在参照 y 坐标基础上，向下偏移参照高度的 50%。',
        '当其值 <0 或 >1 时，表示目标 y 坐标是参照 y 坐标的绝对偏移量。例如 refY: 20 表示，目标 y 坐标在参照 y 坐标基础上，向下偏移 20px。'
      ]
    })
    configDescs.push({
      name: 'refY2',
      desc: '与 refY 一样，当需要同时指定相对偏移量和绝对偏移量时使用。'
    })
    configDescs.push({
      name: 'refDx',
      desc: '设置元素 x 坐标，目标 x 坐标相对于 ref 指代的参照元素的右下角 x 坐标（参照 x 坐标）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 50%）时，表示目标 x 坐标是参照 x 坐标相对于参照元素宽度百分比的相对偏移量。例如 refDx: 0.5 表示，目标 x 坐标在参照 x 坐标基础上，向右偏移参照宽度的 50%。',
        '当其值 <0 或 >1 时，表示目标 x 坐标是参照 x 坐标的绝对偏移量。例如 refDx: 20 表示，目标 x 坐标在参照 x 坐标基础上，向右偏移 20px。'
      ]
    })
    configDescs.push({
      name: 'refDy',
      desc: '设置元素 y 坐标，目标 y 坐标相对于 ref 指代的参照元素的右下角 y 坐标（参照 y 坐标）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 50%）时，表示目标 y 坐标是参照 y 坐标相对于参照元素高度百分比的相对偏移量。例如 refDy: 0.5 表示，目标 y 坐标在参照 y 坐标基础上，向下偏移参照高度的 50%。',
        '当其值 <0 或 >1 时，表示目标 y 坐标是参照 y 坐标的绝对偏移量。例如 refDy: 20 表示，目标 y 坐标在参照 y 坐标基础上，向下偏移 20px。'
      ]
    })
    configDescs.push({
      name: 'refWidth',
      desc: '设置元素宽度，宽度计算相对于 ref 指代的参照元素的宽度（参照宽度）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 75%）时，表示元素的宽度是参照宽度百分之多少。例如 refWidth: 0.75 表示元素的宽度是参照宽度的 75%。',
        '当其值 <0 或 >1 时，表示元素的宽度在参照宽度的基础上减少或增加多少。例如 refWidth: 20 表示元素比相对元素宽 20px。'
      ]
    })
    configDescs.push({
      name: 'refWidth2',
      desc: '与 refWidth 一样，当需要同时指定绝对宽度和相对宽度时使用。'
    })
    configDescs.push({
      name: 'refHeight',
      desc: '设置元素高度，高度计算相对于 ref 指代的参照元素的高度（参照高度）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 75%）时，表示元素的高度是参照高度百分之多少。例如 refHeight: 0.75 表示元素的高度是参照高度的 75%。',
        '当其值 <0 或 >1 时，表示元素的高度在参照高度的基础上减少或增加多少。例如 refHeight: 20 表示元素比相对元素高 20px。'
      ]
    })
    configDescs.push({
      name: 'refHeight2',
      desc: '与 refHeight 一样，当需要同时指定绝对宽度和相对宽度时使用。'
    })
    configDescs.push({
      name: 'refCx',
      desc: '设置元素中心 x 坐标，即原生 cx 属性，目标值计算相对于 ref 指代的参照元素的宽度（参照宽度）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 75%）时，表示元素的 cx 是参照宽度百分之多少。例如 refCx: 0.75 表示元素中心 x 坐标位于参照宽度的 75% 处。',
        '当其值 <0 或 >1 时，表示元素的 cx 是在参照宽度的基础上减少或增加多少。例如 refCx: 20 表示元素中心 x 坐标位于参照宽度加 20px 处。'
      ]
    })
    configDescs.push({
      name: 'refCy',
      desc: '设置元素中心 y 坐标，即原生 cy 属性，目标值计算相对于 ref 指代的参照元素的高度（参照高度）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 75%）时，表示元素的 cy 是参照高度百分之多少。例如 refCy: 0.75 表示元素中心 y 坐标位于参照高度的 75% 处。',
        '当其值 <0 或 >1 时，表示元素的 cy 是在参照宽度的基础上减少或增加多少。例如 refCy: 20 表示元素中心 y 坐标位于参照高度加 20px 处。'
      ]
    })
    configDescs.push({
      name: 'refRx',
      desc: '设置元素的 rx 属性，目标值计算相对于 ref 指代的参照元素的宽度（参照宽度）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 75%）时，表示元素的 rx 是参照宽度百分之多少。例如 refRx: 0.75 表示元素的 rx 是参照宽度的 75%。',
        '当其值 <0 或 >1 时，表示元素的 rx 是在参照宽度的基础上减少或增加多少。例如 refRx: 20 表示元素的 rx 是参照宽度加 20px。'
      ]
    })
    configDescs.push({
      name: 'refRy',
      desc: '设置元素的 ry 属性，目标值计算相对于 ref 指代的参照元素的高度（参照高度）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 75%）时，表示元素的 ry 是参照高度百分之多少。例如 refRy: 0.75 表示元素的 ry 是参照高度的 75%。',
        '当其值 <0 或 >1 时，表示元素的 ry 是在参照宽度的基础上减少或增加多少。例如 refRy: 20 表示元素的 ry 是参照高度加 20px。'
      ]
    })
    configDescs.push({
      name: 'refRCircumscribed',
      desc: '设置元素的 r 属性，目标值相对于 ref 指代的参照元素的对角线长度（参照长度）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 75%）时，表示 r 是参照长度百分之多少。例如 refRCircumscribed: 0.75 表示 r 是参照长度的 75%。',
        '当其值 <0 或 >1 时，表示 r 是在参照长度的基础上减少或增加多少。例如 refRCircumscribed: 20 表示 r 是参照长度加 20px。'
      ]
    })
    configDescs.push({
      name: 'refRInscribed(refR)',
      desc: '设置元素的 r 属性，目标值相对于 ref 指代的参照元素的宽高的最小值（参照长度）',
      details: [
        '当其值在 [0, 1] 之间或为百分比（如 75%）时，表示 r 是参照长度百分之多少。例如 refRInscribed: 0.75 表示 r 是参照长度的 75%。',
        '当其值 <0 或 >1 时，表示 r 是在参照长度的基础上减少或增加多少。例如 refRInscribed: 20 表示 r 是参照长度加 20px。'
      ]
    })
    configDescs.push({
      name: 'refDKeepOffset',
      desc: '设置 <path> 元素的 d 属性。通过缩放原始的 pathData 使目标 <path> 元素的大小与 ref 指代的参照元素的大小一样，通过平移原始的 pathData 使目标 <path> 元素的起点坐标与 ref 指代的参照元素的起点坐标对齐。' + '同时，提供的 pathData 的偏移量将被保留，这意味着如果提供的 pathData 的左上角不在坐标原点 0, 0，当 <path> 元素被渲染到画布后这个偏移量将被保留。'
    })
    configDescs.push({
      name: 'refDResetOffset(refD)',
      desc: '设置 <path> 元素的 d 属性。通过缩放原始的 pathData 使目标 <path> 元素的大小与 ref 指代的参照元素的大小一样，通过平移原始的 pathData 使目标 <path> 元素的起点坐标与 ref 指代的参照元素的起点坐标对齐。' +
        '同时，提供的 pathData 的偏移量将被移除，这意味着如果提供的 pathData 的左上角不在坐标原点 0, 0，将同时通过平移使其位于原点，当 <path> 元素被渲染到画布后将于参照元素严格对齐。'
    })
    configDescs.push({
      name: 'refPointsKeepOffset',
      desc: '设置 <polygon> 或 <polyline> 元素的 points 属性，通过缩放原始点阵使目标元素的大小与 ref 指代的参照元素的大小一样，通过平移原始点阵使目标元素的起点坐标与 ref 指代的参照元素的起点坐标对齐。同时，点阵的偏移量将被保留，这意味着如果点阵的左上角不在坐标原点 0, 0，当元素被渲染到画布后这个偏移量将被保留。'
    })
    configDescs.push({
      name: 'refPointsResetOffset(refPoints)',
      desc: '设置 <polygon> 或 <polyline> 元素的 points 属性，通过缩放原始点阵使目标元素的大小与 ref 指代的参照元素的大小一样，通过平移原始点阵使目标元素的起点坐标与 ref 指代的参照元素的起点坐标对齐。同时，点阵的偏移量将被移除，这意味着如果点阵的左上角不在坐标原点 0, 0，将同时通过平移使其位于原点，当 <path> 元素被渲染到画布后将于参照元素严格对齐。'
    })
    configDescs.push({
      name: 'fill',
      desc: '当提供的 fill 属性值为对象时，表示使用渐变色填充，否则使用字符串颜色填充。'
    })
    configDescs.push({
      name: 'stroke',
      desc: '当提供的 stroke 属性值为对象时，表示使用渐变色填充，否则使用字符串颜色填充。使用方式与 fill 属性一样。'
    })
    configDescs.push({
      name: 'text',
      desc: '仅适用于 <text> 元素，用于设置文本内容。如果提供的文本是单行文本（不包含换行符 \n），那么文本被直接设置为 <text> 元素的内容；否则为每一行文本将创建一个 <tspan> 元素，然后将该元素添加到<text> 元素中'
    })
    return configDescs
  },

  // 获取链接桩位置选项
  getPortPositionOptions() {
    return [{
      label: '顶部均匀分布',
      value: 'top'
    }, {
      label: '底部均匀分布',
      value: 'bottom'
    }, {
      label: '左侧均匀分布',
      value: 'left'
    }, {
      label: '右侧均匀分布',
      value: 'right'
    }, {
      label: '绝对定位',
      value: 'absolute'
    }]
  }
}
